/*
 * Package il.ac.biu.cs.grossmm.api.data
 * File NotificationPoint.java
 * 
 * This is a part of presence service framework API. 
 * See javadoc for more information.
 *  
 * Copyright (C) 2006 Grossmann Mark
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.

 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 
 * MA  02110-1301, USA.
 */

package il.ac.biu.cs.grossmm.api.flow;

import il.ac.biu.cs.grossmm.api.data.Node;
import il.ac.biu.cs.grossmm.api.data.Root;
import il.ac.biu.cs.grossmm.api.keys.Key;

/**
 * API to access notification data point. Notification point is always linked to
 * a notifier. Notifier accepts subscriptions to data nodes with specified keys
 * and sends to the notification point notifications about existance of data
 * node and data modifications.
 * 
 * <pre>
 *             
 *                  +---------------+                     +--------------+ 
 *                  | Notification  |                     |   Notifier   | 
 *                  |     Point     |                     |              |
 *                  +---------------+                     +--------------+
 *                          |                                     |
 *                          |                                     |   (no data associated
 *                          |---------- subscribe (key)----------&gt;|    with the key, access
 *                          |                                     |    denied or data cannot
 *                          |                                     |    be accessed for another
 *                          |&lt;-----deactivated (key, status)------|    reason)
 *                          |                                     |    
 *                          |&lt;----------activated (key)-----------|   (data has been
 *                          |- - - - - -  [node] - - - - - - - - &gt;|    associated with key)
 *                          |                                     |    
 *                          |&lt;----------activated (key)-----------|   (data modified)
 *                          |- - - - - -  [node] - - - - - - - - &gt;|
 *                          |                                     |
 *                          |&lt;----------writeLock (node)----------|    		
 *                          |       ... ( write data ) ...        |
 *                          |&lt;---------writeUnlock (node)---------|
 *                          |                                     |
 *                          |                                     |
 *                          |                                     |
 *                          |&lt;----------writeLock (node)----------|   (data modified)  		
 *                          |       ... ( write data ) ...        |
 *                          |&lt;---------writeUnlock (node)---------|
 *                          |                                     | 
 *                          |                                     |
 *                          |&lt;-----deactivated (key, status)------|   (data removed, 
 *                          |                                     |    access denied, etc)
 *                                    ... ... ... ... ... 
 *                          |                                     |
 *                          |                                     |
 *                          |                                     |
 *                          |&lt;--------unsubscribe (key)-----------| 
 * </pre>
 * 
 */
public interface NotificationPoint<N> {
	/**
	 * Locks a data tree for writing. Ensures that there's no race conditions on
	 * writing operations. This methods returns a <tt>NodeManipulator</tt>
	 * which cah be used to modify data.
	 * <p>
	 * After all modifications has been sucessfully performed, a
	 * <tt>writeUnlock</tt> method must be called to commit these
	 * modifications and unlock the data tree. It is possible to rollback all
	 * the modifications by calling <tt>cancelWrite</tt> method which undoes
	 * all the modifications and unlocks the data tree
	 * <p>
	 * Any modifications performed before calling <tt>writeUnlock</tt> are not
	 * visible via <tt>NodeInspector</tt> methods, but visible via the
	 * returned <tt>NodeManipulator</tt> instance.
	 * 
	 * <p>
	 * The <tt>NodeManipulator</tt> instance returned by this method is valid
	 * until invokation of <tt>writeUnlock</tt> or <tt>writeCancel</tt> for
	 * a node within the same data tree.
	 * 
	 * @param node
	 *            a node to in a data tree to lock for writing
	 * @return <tt>NodeManipulator</tt> to use for modifying the data tree
	 */
	NodeManipulator writeLock(Node node);

	/**
	 * Reverts all modifications applied to the data tree since the lock has
	 * been obtained on a data node within thsi data tree. This methods
	 * automatically releases the lock.
	 * 
	 * @param node
	 *            a node to refer a data tree
	 */
	void cancelWrite(Node node);

	/**
	 * Unlocks the data tree and makes changes visible. Sends notifications to
	 * subscribers for this data tree.
	 * 
	 * @param node
	 *            a node to refer a data tree
	 */
	void writeUnlock(Node node);

	/**
	 * Gets the subscribed data node by key. The key should refer to a
	 * subscribed node. Otherwise the method returns <tt>null</tt> even if
	 * node exists.
	 * 
	 * @param key
	 *            the key
	 * @return the subscribed data node
	 */
	Root<N> getRoot(Key key);

	/**
	 * Gets the subscription state for given key. Returns null if there's
	 * subscription associated with the key
	 * 
	 * @param key
	 *            the key to get the subscription state for
	 * @return the subscription state for given key or null if there's
	 *         subscription associated with the key
	 */
	Status getSubscriptionState(Key key);

	/**
	 * Called when data refered by the given key becomes available.
	 * 
	 * @param key
	 *            a key which refers to a subscribed data
	 * @return the root node in the data tree to write data to
	 */
	Root<N> activated(Key key) throws NoSuchSubscription;

	/**
	 * Called when data refered by the given key becomes unavailable for some
	 * reason.
	 * 
	 * @param key
	 *            a key which refers to a subscribed data
	 * @param status
	 *            status which specifies the reason why data is not available
	 * @throws NoSuchSubscription
	 */
	void deactivated(Key key, Status status)
		throws NoSuchSubscription;
}
